home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / mawk10.zip / RE_CMPL.C < prev    next >
C/C++ Source or Header  |  1991-10-05  |  8KB  |  347 lines

  1.  
  2. /********************************************
  3. re_cmpl.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the AWK programming language.
  8.  
  9. Mawk is distributed without warranty under the terms of
  10. the GNU General Public License, version 2, 1991.
  11. ********************************************/
  12.  
  13. /* $Log:    re_cmpl.c,v $
  14.  * Revision 3.3.1.1  91/09/14  17:24:04  brennan
  15.  * VERSION 1.0
  16.  * 
  17.  * Revision 3.3  91/08/13  06:51:59  brennan
  18.  * VERSION .9994
  19.  * 
  20.  * Revision 3.2  91/06/28  04:17:26  brennan
  21.  * VERSION 0.999
  22.  * 
  23.  * Revision 3.1  91/06/07  10:28:09  brennan
  24.  * VERSION 0.995
  25.  * 
  26.  * Revision 2.4  91/06/05  07:20:33  brennan
  27.  * better error messages when regular expression compiles fail
  28.  * 
  29.  * Revision 2.3  91/06/04  06:47:07  brennan
  30.  * removed <string.h>
  31.  * 
  32.  * Revision 2.2  91/05/28  09:05:07  brennan
  33.  * removed main_buff
  34.  * 
  35.  * Revision 2.1  91/04/08  08:23:45  brennan
  36.  * VERSION 0.97
  37.  * 
  38. */
  39.  
  40.  
  41. /*  re_cmpl.c  */
  42.  
  43. #include "mawk.h"
  44. #include "memory.h"
  45. #include "scan.h"
  46. #include "regexp.h"
  47. #include "repl.h"
  48.  
  49. static  CELL *PROTO( REPL_compile, (STRING *) ) ;
  50.  
  51. typedef struct re_node {
  52. STRING  *sval ;
  53. PTR     re ;
  54. struct re_node *link ;
  55. }  RE_NODE ;
  56.  
  57. static RE_NODE *re_list ;  /* a list of compiled regular expressions */
  58.  
  59. static char efmt[] = "regular expression compile failed (%s)\n%s" ;
  60.  
  61. PTR re_compile( sval )
  62.   STRING *sval ;
  63. { register RE_NODE *p ;
  64.   RE_NODE *q ;
  65.   char *s ;
  66.  
  67.   /* search list */
  68.   s = sval->str ;
  69.   p = re_list ;
  70.   q = (RE_NODE *) 0 ;
  71.   while ( p )
  72.     if ( strcmp(s, p->sval->str) == 0 )  /* found */
  73.         if ( !q ) /* already at front */  goto _return ;
  74.         else /* delete from list for move to front */
  75.         { q->link = p->link ; goto found ; }
  76.     else
  77.     { q = p ; p = p->link ; }
  78.  
  79.   /* not found */
  80.   p = (RE_NODE *) zmalloc( sizeof(RE_NODE) ) ;
  81.   p->sval = sval ;
  82.  
  83.   sval->ref_cnt++ ;
  84.   if( !(p->re = REcompile(s)) )
  85.     if ( mawk_state == EXECUTION )
  86.         rt_error(efmt, REerrlist[REerrno] , s) ;
  87.     else /* compiling */
  88.     { compile_error(efmt, REerrlist[REerrno] , s) ;
  89.       return (PTR) 0 ;
  90.     }
  91.  
  92.  
  93. found :
  94. /* insert p at the front of the list */
  95.   p->link = re_list ; re_list = p ;
  96.  
  97. _return :
  98.   
  99. #ifdef  DEBUG
  100.   if ( dump_RE )  REmprint(p->re, stderr) ;
  101. #endif
  102.   return p->re ;
  103. }
  104.  
  105.  
  106.  
  107. /* this is only used by da() */
  108.  
  109. char *re_uncompile( m )
  110.   PTR  m ;
  111. { register RE_NODE *p ;
  112.  
  113.   for( p = re_list ; p ; p = p->link )
  114.         if ( p->re == m )  return  p->sval->str ;
  115. #ifdef  DEBUG
  116.   bozo("non compiled machine") ;
  117. #endif
  118. }
  119.   
  120.  
  121.  
  122. /*=================================================*/
  123. /*  replacement  operations   */
  124.  
  125. /* create a replacement CELL from a STRING *  */
  126.  
  127. static CELL *REPL_compile( sval )
  128.   STRING  *sval ;
  129. { int i = 0 ;
  130.   register char *p = sval->str ;
  131.   register char *q ;
  132.   char *xbuff ;
  133.   CELL *cp ;
  134.  
  135.   q = xbuff = (char *) zmalloc( sval->len + 1 ) ;
  136.  
  137.   while ( 1 )
  138.   {
  139.       switch( *p )
  140.       {
  141.         case  0  :  *q = 0 ;
  142.                     goto  done  ;
  143.  
  144.         case  '\\':
  145.                 if ( p[1] == '&' )
  146.                 { *q++ = '&' ; p += 2 ; continue ; }
  147.                 else  break ;
  148.  
  149.         case  '&':
  150.                 /* if empty we don't need to make a node */
  151.                 if ( q != xbuff )
  152.                 { *q = 0 ;
  153.                   temp_buff.ptr_buff[i++] = (PTR) new_STRING(xbuff) ;
  154.                 }
  155.                 /* and a null node for the '&'  */
  156.                 temp_buff.ptr_buff[i++] = (PTR) 0  ;
  157.                 /*  reset  */
  158.                 p++ ;  q = xbuff ;
  159.                 continue ;
  160.  
  161.         default :
  162.                 break ;
  163.       }
  164.  
  165.       *q++ = *p++ ;
  166.   }
  167.  
  168. done :   
  169.   /* if we have one empty string it will get made now */
  170.   if ( q > xbuff || i == 0 )
  171.           temp_buff.ptr_buff[i++] = (PTR) new_STRING(xbuff) ;
  172.  
  173.   /* This will never happen */
  174.   if ( i > MAX_SPLIT )
  175.       overflow("replacement pieces", MAX_SPLIT) ;
  176.  
  177.   cp = new_CELL() ;
  178.   if ( i == 1 )
  179.   {
  180.     cp->type = C_REPL ;
  181.     cp->ptr = temp_buff.ptr_buff[0] ;
  182.   }
  183.   else
  184.   {
  185.     STRING **sp = (STRING**)
  186.                   (cp->ptr = zmalloc(sizeof(STRING *)*i)) ;
  187.     int j = 0 ;
  188.  
  189.     while ( j < i ) *sp++ = (STRING *)temp_buff.ptr_buff[j++] ;
  190.  
  191.     cp->type = C_REPLV ;
  192.     cp->vcnt = i ;
  193.   }
  194.   zfree(xbuff, sval->len+1) ;
  195.   return cp ;
  196. }
  197.  
  198. /* free memory used by a replacement CELL  */
  199.  
  200. void  repl_destroy( cp )
  201.   register CELL *cp ;
  202. { register STRING **p ;
  203.   unsigned cnt ;
  204.  
  205.   if ( cp->type == C_REPL )  free_STRING(string(cp)) ;
  206.   else  /* an C_REPLV  */
  207.   {
  208.     p = (STRING **) cp->ptr ;
  209.     for( cnt = cp->vcnt ; cnt ; cnt--) 
  210.     {
  211.       if ( *p ) free_STRING( *p ) ;
  212.       p++ ;
  213.     }
  214.     zfree( cp->ptr, cp->vcnt * sizeof(STRING *) ) ;
  215.   }
  216. }
  217.  
  218. /* copy a C_REPLV cell to another CELL */
  219.  
  220. CELL  *replv_cpy( target, source )
  221.   CELL *target , *source ;
  222. { STRING **t, **s ;
  223.   unsigned cnt ;
  224.  
  225.   target->type = C_REPLV ;
  226.   target->vcnt = source->vcnt ;
  227.  
  228.   target->ptr = (PTR) zmalloc( target->vcnt * sizeof(STRING *) ) ;
  229.   cnt = target->vcnt ;
  230.   t = (STRING **) target->ptr ;
  231.   s = (STRING **) source->ptr ;
  232.   while ( cnt-- )
  233.   { 
  234.     if ( *t = *s++ )   (*t)->ref_cnt++ ;
  235.     t++ ;
  236.   }
  237.   return target ;
  238. }
  239.  
  240. /* here's our old friend linked linear list with move to the front
  241.    for compilation of replacement CELLs  */
  242.  
  243. typedef  struct repl_node {
  244.   struct repl_node  *link ;
  245.   STRING  *sval  ;  /* the input */
  246.   CELL    *cp ;  /* the output */
  247. }  REPL_NODE  ;
  248.  
  249. static  REPL_NODE  *repl_list ;
  250.  
  251. /* search the list (with move to the front) for a compiled
  252.    separator.
  253.    return a ptr to a CELL (C_REPL or C_REPLV)
  254. */
  255.  
  256. CELL *repl_compile( sval )
  257.   STRING *sval ;
  258. { register REPL_NODE *p ;
  259.   REPL_NODE *q ;
  260.   char *s ;
  261.  
  262.   /* search the list */
  263.   s = sval->str ;
  264.   p = repl_list ;
  265.   q = (REPL_NODE *) 0 ;
  266.   while ( p )
  267.     if ( strcmp(s, p->sval->str) == 0 )  /* found */
  268.         if ( !q ) /* already at front */  return p->cp ;
  269.         else /* delete from list for move to front */
  270.         { q->link = p->link ; goto found ; }
  271.     else
  272.     { q = p ; p = p->link ; }
  273.  
  274.   /* not found */
  275.   p = (REPL_NODE *) zmalloc( sizeof(REPL_NODE) ) ;
  276.   p->sval = sval ;
  277.   sval->ref_cnt++ ;
  278.   p->cp = REPL_compile(sval) ;
  279.  
  280. found :
  281. /* insert p at the front of the list */
  282.   p->link = repl_list ; repl_list = p ;
  283.   return p->cp ;
  284. }
  285.  
  286. /* return the string for a CELL or type REPL or REPLV,
  287.    this is only used by da()  */
  288.  
  289. char *repl_uncompile( cp )
  290.   CELL *cp ;
  291. {
  292.   register REPL_NODE *p = repl_list ;
  293.  
  294.   if ( cp->type == C_REPL )
  295.     while ( p )
  296.       if ( p->cp->type == C_REPL &&
  297.            p->cp->ptr  == cp->ptr )   return p->sval->str ;
  298.       else  p = p->link ;
  299.   else
  300.     while ( p )
  301.       if ( p->cp->type == C_REPLV &&
  302.            memcmp( cp->ptr, p->cp->ptr, SIZE_T(cp->vcnt * sizeof(STRING*))) 
  303.            == 0  )   return  p->sval->str ;
  304.       else  p = p->link ;
  305.  
  306.   bozo("unable to uncompile an repl") ;
  307. }
  308.  
  309. /*
  310.   convert a C_REPLV to  C_REPL
  311.      replacing the &s with sval
  312. */
  313.  
  314. CELL  *replv_to_repl( cp, sval)
  315.   CELL *cp ; STRING *sval ;
  316. { register STRING **p ;
  317.   STRING **sblock = (STRING **) cp->ptr ;
  318.   unsigned cnt , vcnt = cp->vcnt ;
  319.   unsigned len ;
  320.   char *target ;
  321.  
  322. #ifdef  DEBUG
  323.   if ( cp->type != C_REPLV ) bozo("not replv") ;
  324. #endif
  325.  
  326.   p = sblock ; cnt = vcnt ; len = 0 ;
  327.   while ( cnt-- )
  328.       if ( *p )  len += (*p++)->len ;
  329.       else
  330.       { *p++ = sval ; sval->ref_cnt++ ; len += sval->len ; }
  331.  
  332.   cp->type = C_REPL ;
  333.   cp->ptr = (PTR) new_STRING((char *) 0, len) ;
  334.  
  335.   p = sblock ; cnt = vcnt ; target = string(cp)->str ;
  336.   while ( cnt-- )
  337.   { (void) memcpy(target, (*p)->str, SIZE_T((*p)->len)) ;
  338.     target += (*p)->len ;
  339.     free_STRING(*p) ;
  340.     p++ ;
  341.   }
  342.  
  343.   zfree( sblock, vcnt * sizeof(STRING *) ) ;
  344.   return cp ;
  345. }
  346.  
  347.